#include <fstream>
#include <iostream>
#include <cstring>

#include <glad/glad.h>
#include <GLFW/glfw3.h>

bool compileShader(const char* filename, unsigned int shader)
{
    std::ifstream vsFile(filename, std::ios::in | std::ios::ate);
    if(vsFile.is_open())
    {
        std::streampos size;
        size = vsFile.tellg();
        char* vsSrc = new char[size]();
        vsFile.seekg(0, vsFile.beg);
        vsFile.read(vsSrc, size);
        vsFile.close();

        glShaderSource(shader, 1, &vsSrc, NULL);
        glCompileShader(shader);

        delete [] vsSrc;

        int success;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if(!success)
        {
            char infoLog[512];
            glGetShaderInfoLog(shader, 512, NULL, infoLog);
            std::cout << "ERROR: Failed to compile shader: " << filename << std::endl;
            std::cout << infoLog << std::endl;
            return false;
        }
    } else {
        std::cout << "Failed to open file: " << filename << std::endl;
        return false;
    }
    
    return true;
}

bool linkProgram(unsigned int vShader, unsigned int fShader, unsigned int shaderProgram)
{
    glAttachShader(shaderProgram, vShader);
    glAttachShader(shaderProgram, fShader);
    glLinkProgram(shaderProgram);

    int success = 0;
    char infoLog[512];
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if(!success)
    {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR: Failed to create shader program. " << std::endl;
        std::cout << infoLog << std::endl;
        return false;
    }
    return true;
}